//
// Created by 74354 on 2022/1/1.
//

#ifndef MYODRIVE_MOTOR_HPP
#define MYODRIVE_MOTOR_HPP



#include "Encoder.hpp"
#include "main.h"
#include "drv8301.h"
#include "stm32f4xx_hal_spi.h"
#include "stm32f405xx.h"
#include "stm32f4xx_hal_gpio.h"
#include "cmsis_os.h"
#include "commuTask.h"
#include "stm32f4xx_hal_tim.h"
#include "foc.h"
#include "printf.h"




class DRV8301_t;
class Motor_t;


class DRV8301_t
{
public:
    enum driverGain{
        gain10VpV,
        gain20VpV,
        gain40VpV,
        gain80VpV
    };

    struct DRV8301_Config{
        float gain;
        odSPI* spi;
        odGPIO_Port* ncsPort;
        odGPIO_Pin ncsPin;
        odGPIO_Port* engatePort;
        odGPIO_Pin  engatePin;
    };

    DRV8301_Obj gate_driver;						// deifne the gate driver infromation
    DRV_SPI_8301_Vars_t gate_driver_regs;		// define the gate driver register
    float v_Gain;
    driverGain gain_param;
    DRV8301_t(){}

    void config(DRV8301_Config* config){
        gate_driver.EngpioHandle = config->engatePort;
        gate_driver.EngpioNumber = config->engatePin;
        gate_driver.nCSgpioHandle = config->ncsPort;
        gate_driver.nCSgpioNumber = config->ncsPin;
        gate_driver.spiHandle = config->spi;
        v_Gain = config->gain;
        if(v_Gain == 10)gain_param = gain10VpV;
        if(v_Gain == 20)gain_param = gain20VpV;
        if(v_Gain == 40)gain_param = gain40VpV;
        if(v_Gain == 80)gain_param = gain80VpV;
    }
    void setup();
};


class MotorProperties{
public:
    bool pre_calibrated = false; // can be set to true to indicate that all values here are valid
    uint8_t pole_pairs = 7;
    float resistance_calib_max_voltage;
    float phase_inductance = 0.0f;        // to be set by measure_phase_inductance
    float phase_resistance = 0.0f;        // to be set by measure_phase_resistance
    float current_lim = 10.0f;          //[A]
    float voltage_lim = 12.0f;          //[V]

    float torque_lim;           //[Nm]

};

class Motor_t:public MotorProperties{
public:

    Motor_t(){}
    struct Motor_Config{
        int data;
    };

    int i_phase_offset[3] = {0,0,0};
    bool is_calibrated_encoder = false;
    bool is_calibrated_motor = false;
    DRV8301_t*  driver;
    Encoder_t* encoder;
    FOC* foc_controller;
    void calibrate_encoder();
    void calibrate_motor();
    bool motorOK = false;
    int  iABC_dig[3];
    float iABC_ANO [3];

    inline float getMachineRad();
    void config(Motor_Config* config){};
    void compute_Current();

    void set_Encoder(Encoder_t::EncoderType_t type,uint32_t cpr,odTIM timer);
    void set_FOC(float u_dc,uint16_t ts,odTIM timer);

};

void Drv8301PrintInf(DRV_SPI_8301_Vars_t *regs);

#endif //MYODRIVE_MOTOR_HPP
